package sitemapValidator;

import java.io.IOException;

import javax.servlet.http.*;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.SchemaFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

@SuppressWarnings("serial")
public class Sitemap_ValidatorServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		String News, Image, Code, Geo, Video, Web, Index, Type, Type_public;
		Web 	= "http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd";
		Index   = "http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd";
		News    = "http://www.google.com/schemas/sitemap-news/0.9/sitemap-news.xsd";
		Image   = "http://www.google.com/schemas/sitemap-image/1.1/sitemap-image.xsd";
		Code    = "http://www.google.com/codesearch/schemas/sitemap/1.0/sitemap-codesearch.xsd";
		Geo     = "http://www.google.com/geo/schemas/sitemap/1.0/sitemap-geo.xsd";
		Video   = "http://www.google.com/schemas/sitemap-video/1.1/sitemap-video.xsd";
		Type	= "";
		Type_public = "";
		resp.setContentType("text/html");
		resp.getWriter().println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" +
				"<html xmlns=\"http://www.w3.org/1999/xhtml\">" +
				"<head>" +
				"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />" +
				"<title>Sitemap Validation Service</title>" +
				"<meta name=\"description\" content=\"Simple service which for validating various types of sitemaps supported by Google, including Web, Sitemap Index, News, Video, Image, Code Search and Geo sitemaps\" />" +
				"<link href=\"/style/style.css\" rel=\"stylesheet\" type=\"text/css\" />" +
				"<!--[if IE]>" +
				"<style type=\"text/css\">" +
				".thrColLiqHdr #sidebar2, .thrColLiqHdr #sidebar1 { padding-top: 30px; }" +
				".thrColLiqHdr #mainContent { zoom: 1; padding-top: 15px; }" +
				"#se_res {overflow:inherit!important;}" +
				"</style>" +
				"<![endif]-->" +
				"</head>" +
				"<body class=\"thrColLiqHdr\">" +
				"<div id=\"container\">" +
				"<div id=\"header\">" +
				"<div class=\"hboxL\">" +
				"<a href=\"./\" style=\"text-decoration:none\"><h1 style=\"color:#069; font-family:'Courier New', Courier, monospace\">Sitemap<span style=\"color:#06C; font-size:18px;\">Validation</span></h1></a>" +
				"</div>" +
				"<div class=\"hboxr\">" +
				"</div>" +
				"<div class=\"hline\"></div>" +
				"</div>" +
				"<div id=\"sidebar1\">" +
				"<h4>Useful links</h4>" +
				"<ul>" +
				"<li><a href='http://sitemaps.org' title='Sitemaps.org'>Web Sitemap specification</a></li>" +
				"<li><a href='http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=74288' title='News Sitemap Specification'>News Sitemap Specification</a></li>" +
				"<li><a href='http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=80472' title='Video Sitemap Specification'>Video Sitemap Specification</a></li>" +
				"<li><a href='http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=75224' title='Code Search Sitemap Specification'>Code Search Sitemap Specification</a></li>" +
				"<li><a href='http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=94555' title='Geo Sitemap Specification'>Geo Sitemap Specification</a></li>" +
				"<li><a href='http://www.google.com/support/webmasters/bin/answer.py?hl=en&answer=178636' title='Image Sitemap Specification'>Image Sitemap Specification</a></li>" +
				"<li>&nbsp;</li>"+
				"<li><a href='http://www.google.com/webmasters/' title='Google Webmaster Central'>Google Webmaster Central</a></li>" +
				"<li><a href='http://www.google.com/support/forum/p/Webmasters?hl=en' title=''>Google Webmaster Help Forum</a></li>" +
				"</ul>" +
				"</div>" +
				"<div id='mainContent'>");
		if(req.getParameter("url") != null){
			String RawType = new String(req.getParameter("type"));
			if(RawType.equals(new String("news"))){
				Type = News;
				Type_public = "News Sitemap (news-0.9.xsd)";
			}else if(RawType.equals(new String("image"))){
				Type = Image;
				Type_public = "Image Sitemap (image-1.1.xsd)";
			}else if(RawType.equals(new String("code"))){
				Type = Code;
				Type_public = "Codesearch Sitemap (code-1.0.xsd)";
			}else if(RawType.equals(new String("geo"))){
				Type = Geo;
				Type_public = "Geo Sitemap (geo-1.0.xsd)";
			}else if(RawType.equals(new String("video"))){
				Type = Video;
				Type_public = "Video Sitemap (video-1.1.xsd)";
			}else if(RawType.equals(new String("index"))){
				Type = Index;
				Type_public = "Sitemap Index (index-0.9.xsd)";
			}else  if(RawType.equals(new String("web"))){
				Type = Web;
				Type_public = "Web Sitemap (sitemap-0.9.xsd)";
			}else{
				resp.getWriter().println("Umm... can't read the Type argument's value for some reason...<br />\n");
			}
			resp.getWriter().println("<sup>&laquo;<a href='./'>back</a></sup><br /><br />Validating against " + Type_public + " schema definition<br />\n");
			resp.getWriter().println("Source location: " + req.getParameter("url") + " <a href='"+ req.getParameter("url") +"' target='_blank' title='Opens in new tab' ><img src='/style/url_icon.gif' /></a><hr /><br />\n");
			try {
				SAXParserFactory factory = SAXParserFactory.newInstance();
				factory.setValidating(false);
				factory.setNamespaceAware(true);

				SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
				if(RawType != "web"){
					if(RawType.equals(new String("index"))){
						factory.setSchema(schemaFactory.newSchema(
								new Source[] {new StreamSource(Index)}));
					}else{
						factory.setSchema(schemaFactory.newSchema(
								new Source[] {new StreamSource(Web),
											new StreamSource(Type)}));
					}
				}else{
					factory.setSchema(schemaFactory.newSchema(
							new Source[] {new StreamSource(Web)}));
				}
				SAXParser parser = factory.newSAXParser();
				
				XMLReader reader = parser.getXMLReader();
				SimpleErrorHandler errorer = new SimpleErrorHandler();
				reader.setErrorHandler(errorer);
				try{
					reader.parse(new InputSource(new String(req.getParameter("url"))));
					
					if(errorer.validationError==true){    
						resp.getWriter().println("<strong style='color:red'>XML Document is not valid!\n</strong><br /> "+errorer.saxParseException);
					}else{  
						resp.getWriter().println("<strong style='color:green'>XML Document is valid</strong>");
					}
				}catch(Exception e){
					resp.getWriter().println("<strong style='color:red'>An error occured:</strong> " + e.getMessage()+"<br />Please use absolute URIs, for example <code>http://example.com/sitemap.xml</code>");
				}
			} catch (ParserConfigurationException e3) {
				resp.getWriter().println("<strong style='color:red'>An error occured:</strong> " + e3.getMessage());
			} catch (SAXException e) {
				resp.getWriter().println("<strong style='color:red'>An error occured:</strong> " + e.getMessage());
			}
		}else{
			resp.getWriter().println("<form method='get' action='/sitemap_validator' class='fo'>" +
					"<p><strong>The location of your sitemap:</strong></p>" +
					"<p style='text-align: center'><input type='text' name='url' class='url'  /></p>" +
					"<p style='margin-top:20px;'><strong>Type of the sitemap:</strong></p>" +
					"<p style='text-align: center'><label class='sm_label'>Web Sitemap<input type='radio' name='type' value='web' checked='checked' /></label>" +
					"<label class='sm_label'>News Sitemap<input type='radio' name='type' value='news' /></label>" +
					"<label class='sm_label'>Video Sitemap<input type='radio' name='type' value='video' /></label>" +
					"<label class='sm_label'>Geo Sitemap<input type='radio' name='type' value='geo' /></label>" +
					"<label class='sm_label'>Image Sitemap<input type='radio' name='type' value='image' /></label>" +
					"<label class='sm_label'>Code Sitemap<input type='radio' name='type' value='code' /></label>" +
					"<label class='sm_label'>Sitemap Index <input type='radio' name='type' value='index' /></label>" +
					"</p>" +
					"<p><input type='submit' value=' Validate sitemap ' /></p>" +
					"</form>");
		}
		resp.getWriter().println("</div><!-- #ends main content -->" +
				"<br class=\"clearfloat\" />" +
				"<div id=\"footer\">" +
				"<p style=\"text-align:right\">" +
				"<a href=\"http://appengine.google.com\" target=\"_blank\"><img src=\"http://code.google.com/appengine/images/appengine-silver-120x30.gif\" alt=\"Powered by Google App Engine\" /></a>" +
				"</p>" +
				"</div><!-- end #footer -->" +
				"</div><!-- end #container -->" +
				"</body>" +
				"</html>");
	}
}
